package vista;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Observable;
import java.util.Observer;

import javax.swing.DefaultListModel;
import javax.swing.ListSelectionModel;

import colaDeProduccion.ColaDeProduccion;
import colaDeProduccion.Producto;

import mapas.Region;
import control.construirEdificio.BotonConstruirListener;
import control.construirEdificio.ProductoAeropuerto;
import control.construirEdificio.ProductoCasa;
import control.construirEdificio.ProductoEdificio;
import control.construirEdificio.ProductoEscMilitar;
import control.construirEdificio.ProductoFabrica;
import control.construirEdificio.ProductoFabricaMil;
import control.juego.ControladorSeleccion;
import control.ronda.controladorFinTurno;

/**
 * @author Grupo 2, Algoritmos y programacion 3, Catedra Fontela<br>1er cuat 2007    
 * <br> Esta clase se encarga de representar la vista para construir edificios.
 */

public class VistaConstruirEdificio extends VentanaConDosListas implements Observer, CerrablePorFinTurno{

	//Modelo
	private Region region;
	private ColaDeProduccion colaProdRegion;
	
	private static String subtitulo1 = "Edificio a Comprar";
	private static String subtitulo2 = "Cola de Produccion";
	private static String accion = "Comprar";
	
	private static VistaConstruirEdificio Instance = null; //Instancia de la ventana
	
	/**
	 * Se encarga de inicializar la vista de construccion
	 * @param titulo Titulo de la ventana
	 */
	private VistaConstruirEdificio(String titulo){
		//Llamo al constructor del padre
		super(titulo, subtitulo1, subtitulo2, accion);
		//agrego la funcionalidad a los botones
		this.ActivarComportamientoBotonAccion();
		this.ActivarComportamientoBotonSalir();
		//cargo los productos disponibles
		this.CargarProductos(getModelo1());
		//agrego la intancia 
		Instance = this;
		//agrego esta vista como cerrable al finalizar el turno
		controladorFinTurno.getInstance().agregarVistaCerrable(this);
	}
	
	/**
	 * @return La unica instancia de la VistaConstruirEdificio
	 */
	public static VistaConstruirEdificio getInstance(){
		if ( Instance == null)
			new VistaConstruirEdificio(" - CONSTRUIR EDIFICIO - ");
		Instance.actualizarModelo();
		return Instance;
	}
	
	/**
	 * Coloca la nueva region con su cola de produccion
	 */
	private void actualizarModelo(){
		if (region != null)
			region.deleteObserver(this);
		if (colaProdRegion != null){
			colaProdRegion.deleteObserver(this);
			borrarObservadoresProductos(colaProdRegion);
		}
		//Conecto con el modelo
		this.region = ControladorSeleccion.GetInstance().getSlot1();
		if (region!=null){
			region.addObserver(this);
			colaProdRegion = region.getColaProduccionEdificios();
			this.setTitle(" - CONSTRUIR EDIFICIO EN " + region.getNombre() + " - ");
		} else {
			colaProdRegion = null;
			this.setTitle(" - CONSTRUIR EDIFICIO EN NINGUNA - ");
		}	
		if (colaProdRegion!=null)
			colaProdRegion.addObserver(this);
		this.update(null,null);
	}
	
	/**
	 * Establece los modos de seleccion de las listas.
	 */
	protected void establecerModosDeSeleccion(){
		getLista1().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		getLista2().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
	}
	
	/**
	 * Se encarga de actualizar la vista, cuando el modelo cambie
	 */
	public void update(Observable arg0, Object arg1) {
		//Remuevo todos los elementos de las lista 2
		this.getModelo2().removeAllElements();
		//Actualizo la lista con la cola de produccion
		if (colaProdRegion != null)
			ActContenidoColaProd(this.getModelo2(), colaProdRegion);
	}

	/**
	 * Carga los productos disponibles para comprar en la region
	 * @param modeloLista Modelo donde cargar los Productos
	 */
	private void CargarProductos(DefaultListModel modeloLista){
		//Creo los distintos productos disponibles
		ProductoEdificio[] productos = new ProductoEdificio[5];
		productos[0] = new ProductoCasa();
		productos[1] = new ProductoEscMilitar();
		productos[2] = new ProductoFabrica();
		productos[3] = new ProductoFabricaMil();
		productos[4] = new ProductoAeropuerto();
		//Los agrego a la lista
		for (int cont = 0; cont < 5; cont++){
			modeloLista.addElement(productos[cont]);
		}
	}
	
	/**
	 * Actualiza la lista con el contenido de la cola de produc
	 * @param modeloLista Modelo donde cargar las unidades
	 * @param cola Cola de produccion que contiene los edificios creados
	 */
	private void ActContenidoColaProd(DefaultListModel modeloLista, ColaDeProduccion cola){
		//Obtengo los productos
		ArrayList productos = cola.getProductos();
		//Monto un iterador y recorro los elementos
		Iterator iterador = productos.iterator();
		while (iterador.hasNext()){
			//Obtengo cada producto, extraigo el contenido y lo agrego al modelo de la lista
			Producto producto = (Producto) iterador.next();
			modeloLista.addElement(producto);
			producto.addObserver(this);
		}
	}

	/**
	 * Saca a la vista como observadora de los productos de la cola pasada por parametro
	 * @param cola Cola de produccion
	 */
	private void borrarObservadoresProductos(ColaDeProduccion cola){
		//Obtengo los productos
		ArrayList productos = cola.getProductos();
		//Monto un iterador y recorro los elementos
		Iterator iterador = productos.iterator();
		while (iterador.hasNext()){
			//Obtengo cada producto y borro a la vista como observadora
			Producto producto = (Producto) iterador.next();
			producto.deleteObserver(this);
		}
	}
	
	/**
	 * @return La region donde se esta construyendo
	 */
	public Region getRegion(){
		return this.region;
	}
	
	/**
	 * Activa el comportamiento del boton accion.
	 * Le asigna la accion de construir.
	 */
	protected void ActivarComportamientoBotonAccion(){
		this.getBotonAccion().addActionListener(new BotonConstruirListener(this));
	}
	
	public void CerrarVentana() {
		this.setVisible(false);
	}
}
